package com.kitty.game.friend.service;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.FieldValuePosConst;
import com.kitty.game.ServerService;
import com.kitty.game.chat.message.RespChat;
import com.kitty.game.chat.model.OfflineMessage;
import com.kitty.game.chat.model.RoleOfflineMessage;
import com.kitty.game.config.Server;
import com.kitty.game.confirm.model.AddBlackConfirm;
import com.kitty.game.confirm.model.AddFriendConfirm;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespNotifyMisc;
import com.kitty.game.enter.RespUpdate;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.friend.message.*;
import com.kitty.game.friend.message.vo.VerifyFriendInfo;
import com.kitty.game.friend.model.*;
import com.kitty.game.i18n.I18nId;
import com.kitty.game.i18n.I18nIdDataPool;
import com.kitty.game.map.service.MapService;
import com.kitty.game.market.MarketService;
import com.kitty.game.market.message.RespExchangeContactSeller;
import com.kitty.game.market.model.Goods;
import com.kitty.game.player.PlayerService;
import com.kitty.game.player.model.PlayerProfile;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.team.message.RespConfirm;
import com.kitty.game.team.message.RespFriendAddRole;
import com.kitty.game.team.message.RespFriendUpdatePartial;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.utils.*;
import com.kitty.game.welfare.model.CommonFetchedData;
import com.kitty.game.zhenbao.ZhenbaoService;
import com.kitty.listener.EventType;
import com.kitty.listener.annotation.EventHandler;
import com.kitty.listener.event.LoginEvent;
import com.kitty.listener.event.LogoutEvent;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.Message;
import com.kitty.mina.message.MessagePusher;
import com.kitty.mina.task.ThreadLocalUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

@Service
public class FriendService {
    Logger logger = LoggerFactory.getLogger(FriendService.class);

    @Autowired
    Dao dao;
    @Autowired
    MapService mapService;
    @Autowired
    RoleService roleService;
    @Autowired
    EquipService equipService;
    @Autowired
    ServerService serverService;
    @Autowired
    PlayerService playerService;
    /**
     * 登出
     */
    @EventHandler(EventType.LOGOUT)
    public void handleLogoutEvent(LogoutEvent logoutEvent) {
        Role role = logoutEvent.getRole();
        /**下线的时候给好友通知*/
        sendOnlineStatus(role, false);
        removeBeFriend(role);
    }

    @EventHandler(EventType.LOGIN)
    public void handleLoginEvent(LoginEvent loginEvent) {
        Role role = loginEvent.getRole();
        serverService.getScheduledExecutorService().schedule(new Runnable() {
            @Override
            public void run() {

                RespFriendGroup respFriendGroup = new RespFriendGroup(); //好友分组
                respFriendGroup.setList(role.getFriendBox().getFriendGroup());
                MessagePusher.pushMessage(role, respFriendGroup);

                // 循环加载
                for(FriendGroup friendGroup : role.getFriendBox().getFriendGroup()){
                    RespNewGroup respNewGroup = new RespNewGroup();
                    respNewGroup.setFriendGroup(friendGroup);
                    MessagePusher.pushMessage(role, respNewGroup);
                }


                loadFriends(role);
                sendOnlineStatus(role, true);//通知好友上线信息
                addBeFriend(role);
                ThreadLocalUtil.addLocalTask(role, () -> sendOfflineMessageLogin(role));
            }
        },3, TimeUnit.SECONDS);

    }

    /**
     * 取新分组编号
     */
    private String getNewGroupNumber(List<FriendGroup> list) {
        int newNumber = 1;
        while (true) {
            newNumber++;
            boolean isExist = false;
            for (FriendGroup Group : list) {
                if (Group.getNumber().equals(newNumber + "")) {
                    isExist = true;
                }
            }
            if (isExist || newNumber == 5 || newNumber == 6) {
                continue;
            } else {
                break;
            }
        }
        return newNumber + "";
    }

    /**
     * 增加好友分组
     */
    public void addFriendGroup(IoSession session, ReqAddFriendGroup reqAddFriendGroup) {
        Role role = SessionUtils.getRoleBySession(session);
        List<FriendGroup> list = role.getFriendBox().getFriendGroup();
        for (FriendGroup friendGroup : list) {
            if (friendGroup.getGroupName().equals(reqAddFriendGroup.getGroupName())) {
                MessagePusher.pushMessage(session, new RespMsg("分组名已存在。"));
                return;
            }
        }

        FriendGroup friendGroup = new FriendGroup();
        friendGroup.setGroupName(reqAddFriendGroup.getGroupName());
        friendGroup.setNumber(getNewGroupNumber(list));
        list.add(friendGroup);
        role.getFriendBox().setFriendGroup(list);
        role.save();

        RespNewGroup respNewGroup = new RespNewGroup();
        respNewGroup.setFriendGroup(friendGroup);
        MessagePusher.pushMessage(session, respNewGroup);

        MessagePusher.pushMessage(session, new RespMsg("创建分组成功。"));
    }

    /**
     *添加好友
     */
    public void reqAddFriend(Role role, String friendName) {
        Role friend = SpringUtils.getRoleService().getOnlinePlayer(friendName);
        if (!canAddFriend(role, friendName)) return;

        /**判断是否需要验证*/
        if (isVerifyAdd(role, friend)) {
            /**需要验证*/

            if (isReqVerifyAdd(role, friend)) {
                /**已经申请*/
                MessagePusher.notify2Player(role, I18nId.PMT_1301, friendName);
            } else {
                /**弹出验证申请*/
                popReqVerify(role, friend);
            }
        } else {
            /**不需要验证，直接添加好友*/
            doAddFriend(role, friend, "1", true);
        }
    }

    private boolean canAddFriend(Role role, String friendName) {
        Role friend = SpringUtils.getRoleService().getOnlinePlayer(friendName);
        /**对方不在线*/
        if (friend == null) {
            MessagePusher.notify2Player(role, I18nId.PMT_1300, friendName);
            return false;
        }
        /**对方开启了拒绝等级条件*/
        if (isRefuseAdd(role, friend)) {
            MessagePusher.notify2Player(role, I18nId.PMT_1305);
            return false;
        }
        /**拒绝两次后，需要等级半个钟*/
        if (isWaitAdd(role, friend)) {
            MessagePusher.notify2Player(role, I18nId.PMT_1306, friendName);
            return false;
        }
        /**在黑名单中无法添加*/
        if (isBlack(role, friend.getName())) {
            MessagePusher.notify2Player(role, I18nId.PMT_1312, friendName);
            return false;
        }
        /**在对方黑名单中无法添加*/
        if (isBlack(friend, role.getName())) {
            MessagePusher.notify2Player(role, I18nId.PMT_1313, friendName);
            return false;
        }
        return true;
    }

    /**
     * 是否拒绝添加好友
     */
    private boolean isRefuseAdd(Role role, Role friend) {
        /**开启拒绝开关且等级小于拒绝等级*/
        return friend.getExtendBox().getSetMap().getOrDefault("refuse_be_added", 0) == 1 && role.getLevel() < friend.getFriendBox().getRefuseLevel();
    }

    /**
     * 是否需要等待
     */
    private boolean isWaitAdd(Role role, Role friend) {
        if (role.getFriendBox().getRefuseMap() != null && role.getFriendBox().getRefuseMap().containsKey(friend.getUid())) {
            FriendRefuse friendRefuse = role.getFriendBox().getRefuseMap().get(friend.getUid());
            if (friendRefuse.getCount() >= 2 && System.currentTimeMillis() < friendRefuse.getRefuseTime() + Const.FRIEND_REFUSE_WAIT_MINUTE* TimeUtil.ONE_MINUTE) {
                return true;
            }
        }

        return false;
    }

    /**添加好友是否需要验证*/
    private boolean isVerifyAdd(Role role, Role friend) {
        /**判断自己是不是对方好友 是的话不需要验证，直接添加*/
        if (friend.getFriendBox().getFriendByGid(role.getGid()) != null) {
            return false;
        }
        /**没有开启验证且等级达到验证等级时，则不需要验证*/
        if (friend.getExtendBox().getSetMap().getOrDefault("verify_be_added", 0) == 0
                && role.getLevel() >= Const.FRIEND_ADD_VERIFY_LEVEL) {
            return false;
        }

        return true;
    }

    /**
     * 是否已经申请过添加好友验证
     */
    private boolean isReqVerifyAdd(Role reqRole, Role friend) {
        return friend.getFriendBox().getVerifyMap() != null && friend.getFriendBox().getVerifyMap().containsKey(reqRole.getUid()) && System.currentTimeMillis() < (friend.getFriendBox().getVerifyMap().get(reqRole.getUid()) + (Const.FRIEND_VERIFY_WAIT_MINUTE*TimeUtil.ONE_MINUTE));
    }

    /**
     * 弹出申请验证界面
     */
    private void popReqVerify(Role role, Role friend) {
        RespVerifyInfo respVerifyInfo = new RespVerifyInfo();
        respVerifyInfo.setFriendName(friend.getName());
        respVerifyInfo.setMianbanId(friend.getGid());
        MessagePusher.pushMessage(role, respVerifyInfo);
    }

    /**
     * 执行添加好友
     */
    private void doAddFriend(Role role, Role friend, String groupNumber, boolean isRoleOp) {
        Friend newFriend = newFriend(friend.getGid(), friend.getName(), groupNumber);
        addFriend(role, newFriend);//插入数据库
        addBeFriend(role.getUid(), friend.getUid());

        /**通知申请人*/
        sendFriendInfo(role, newFriend, groupNumber);
        MessagePusher.notify2Player(role, I18nId.PMT_1302, friend.getName());

        if (isRoleOp) {
            RespAddFriendOper respAddFriendOper = new RespAddFriendOper();
            respAddFriendOper.setGid(friend.getGid());
            respAddFriendOper.setName(friend.getName());
            respAddFriendOper.setPartyName(friend.getPartyName());
            respAddFriendOper.setIcon(friend.getRoleIcon());
            respAddFriendOper.setLevel(friend.getLevel());
            MessagePusher.pushMessage(role, respAddFriendOper);
        }

        /**通知对方*/
        MessagePusher.notifyMisc2Player(friend, I18nId.PMT_1303, role.getName());

        /**判断对方是否添加好友，没添加时提示是否添加*/
        if (friend.getFriendBox().getFriendByGid(role.getGid()) == null
                && !(friend.getTalk().isInTalk() || SpringUtils.getFightService().isInFight(friend))) {
            friend.setConfirm(new AddFriendConfirm(role));

            String content = I18nIdDataPool.getI18nContent(I18nId.PMT_1304, role.getName());
            RespConfirm respConfirm = new RespConfirm();
            respConfirm.setTips(content);
            MessagePusher.pushMessage(friend, respConfirm);
        }
    }

    private Friend newFriend(String gid, String name, String groupNumber) {
        Friend friend = new Friend();
        friend.setFriendName(name);
        friend.setGid(gid);
        friend.setGroupNumber(groupNumber);
        return friend;
    }

    /**
     * 发送验证消息给好友
     */
    public void sendVerifyInfo(IoSession session, ReqVerifyInfo reqVerifyInfo) {
        Role role = SessionUtils.getRoleBySession(session);
        Role friend = SpringUtils.getRoleService().getOnlinePlayer(reqVerifyInfo.getFriendName());
        if (friend == null) {
            return;
        }

        RespVerifyInfoList respVerifyInfoList = new RespVerifyInfoList();
        List<VerifyFriendInfo> list = new ArrayList<>(1);
        respVerifyInfoList.setList(list);
        VerifyFriendInfo verifyFriendInfo = new VerifyFriendInfo();
        verifyFriendInfo.setId(friend.getGid());
        verifyFriendInfo.setType((short) 1);
        verifyFriendInfo.setSender(role.getName());
        verifyFriendInfo.setTitle(role.getGid());
        String attachement = String.format("%d;%d;;0", role.getLevel(), role.getRoleIcon());
        verifyFriendInfo.setAttachement(attachement);
        int currTime = (int) (System.currentTimeMillis() / TimeUtil.ONE_MINUTE);
        int endTime = currTime + 60 * 10;
        verifyFriendInfo.setCreateTime(currTime);
        verifyFriendInfo.setExpiredTime(endTime);
        verifyFriendInfo.setStatus((short) 0);

        list.add(verifyFriendInfo);

        MessagePusher.pushMessage(friend, respVerifyInfoList);
    }

    /**
     * 添加好友
     */
    private void addFriend(Role role, Friend newFriend) {
        Friend friend = role.getFriendBox().getFriendByGid(newFriend.getGid());
        if (friend == null) {
            role.getFriendBox().getFriends().add(newFriend);
            role.save();
        }
    }

    /**
     * 登录加载好友信息
     */
    public void loadFriends(Role role) {
        List<Friend> list = role.getFriendBox().getFriends();
        RespFriendMemo respFriendMemo = new RespFriendMemo();
        ArrayList<FriendMemo> friendMemos = new ArrayList<>();

        for (Friend friend : list) {
            Role friendRole = SpringUtils.getRoleService().getPlayerBy(Long.parseLong(friend.getGid()));
            if (friendRole == null){
                continue;
            }
            friend.setFriendName(friendRole.getName());
            FriendMemo friendMemo = new FriendMemo();
            friendMemo.setGid(friend.getGid());
            friendMemo.setMemo(friend.getMark() != null ? friend.getMark() : "");
            friendMemos.add(friendMemo);
            sendFriendInfo(role, friend, friend.getGroupNumber());
        }
        respFriendMemo.setFriendMemos(friendMemos);
        MessagePusher.pushMessage(role, respFriendMemo);
    }

    /**
     * 接收加好友请求
     */
    public void acceptRequest(IoSession session, ReqAcceptRequest reqAcceptRequest) {
        Role role = SessionUtils.getRoleBySession(session);
        if (role == null) {
            return;
        }

        Role friend = SpringUtils.getRoleService().getOnlinePlayer(reqAcceptRequest.getFriendName());

        RespVerifyInfoList respVerifyInfoList = new RespVerifyInfoList();
        List<VerifyFriendInfo> list = new ArrayList<>(1);
        respVerifyInfoList.setList(list);
        VerifyFriendInfo verifyFriendInfo = new VerifyFriendInfo();
        verifyFriendInfo.setId(role.getGid());
        verifyFriendInfo.setType((short) 1);
        verifyFriendInfo.setSender(friend != null ? friend.getName() : "");
        verifyFriendInfo.setTitle(friend != null ? friend.getGid() : "");
        String attachement = friend != null ? String.format("%d;%d;;0", friend.getLevel(), friend.getRoleIcon()) : "";
        verifyFriendInfo.setAttachement(attachement);
        int currTime = (int) (System.currentTimeMillis() / TimeUtil.ONE_MINUTE);
        int endTime = currTime + 60 * 10;
        verifyFriendInfo.setCreateTime(currTime);
        verifyFriendInfo.setExpiredTime(endTime);
        verifyFriendInfo.setStatus((short) 3);

        list.add(verifyFriendInfo);

        MessagePusher.pushMessage(role, respVerifyInfoList);


        if (friend == null) {
            return;
        }
        boolean accept = reqAcceptRequest.isAccept();
        if (accept) {//接受
            if (!canAddFriend(friend, role.getName())) return;

            doAddFriend(friend, role, "1", false);
        } else {//拒绝
            MessagePusher.notify2Player(friend, I18nId.PMT_1307, role.getName());
            addRefuseRecord(friend, role);
        }
    }

    /**
     * 添加拒绝记录
     */
    private void addRefuseRecord(Role reqRole, Role role) {
        if (reqRole.getFriendBox().getRefuseMap() == null) {
            reqRole.getFriendBox().setRefuseMap(new HashMap<>(4));
        }
        FriendRefuse friendRefuse = reqRole.getFriendBox().getRefuseMap().get(role.getUid());
        if (friendRefuse == null) {
            friendRefuse = new FriendRefuse();
            reqRole.getFriendBox().getRefuseMap().put(role.getUid(), friendRefuse);
        }
        friendRefuse.setCount((byte) (friendRefuse.getCount() + 1));
        friendRefuse.setRefuseTime(System.currentTimeMillis());
    }

    /**确认添加好友*/
    public void confirmAddFriend(Role role, Role target) {
        if (!canAddFriend(role, target.getName())) return;
        doAddFriend(role, target, "1", false);
    }


    /**
     * 发送好友信息
     *
     * @param toRole
     * @param friend
     *
     */

    public void sendFriendInfo(Role toRole, Friend friend, String group) {
        RoleView roleView = new RoleView(Long.parseLong(friend.getGid()));
        boolean isLine = roleService.isOnline(Long.parseLong(friend.getGid()));
        byte lineStatus = (byte) (isLine ? 1 : 2);
        String lineName = isLine ? serverService.getServer().getSonName() : "不在线";

        {
            RespFriendAddRole respFriendAddRole = new RespFriendAddRole();
            respFriendAddRole.setName(friend.getFriendName());
            respFriendAddRole.setType1((short) 1);
            respFriendAddRole.setType(group); //1好友列表 6应该是陌生人
            respFriendAddRole.setLineName(lineName);
            ArrayList<FiedValue> arrayList = new ArrayList<>();
            NutMap propsStatus = toRole.getPropsStatus();
            arrayList.add(new FiedValue(3024, propsStatus == null?"":propsStatus.getString("liaotiandikuang","")));//聊天框
            arrayList.add(new FiedValue(3023, propsStatus == null ?"":propsStatus.getString("touxiangkuang",""))); // 头像框
            
            arrayList.add(new FiedValue(301, 0));
            arrayList.add(new FiedValue(304, ""));
            arrayList.add(new FiedValue(302, 0));
            arrayList.add(new FiedValue(334, 0));
            arrayList.add(new FiedValue(292, roleView.getRoleIcon()));
            arrayList.add(new FiedValue(31, roleView.getLevel()));
            arrayList.add(new FiedValue(3012, lineName));
            arrayList.add(new FiedValue(40, roleView.getRoleIcon()));
            arrayList.add(new FiedValue(290, roleView.getWeaponIcon()));//weapon_icon


            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 290);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 33);//帮派名
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(roleView.getPartyName());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 880);
                fiedValue.setVT((byte) 1);
                fiedValue.setValue((byte) 0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 90);
                fiedValue.setVT((byte) 4);
                fiedValue.setValue("");
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 81);//门派名
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(roleService.getFamilyName(roleView.getPolar()));
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 36);//称号
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(roleView.getCurrTitle());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 291);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 305);//面板ID
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(friend.getGid());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 27);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 21);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 194);//在线状态
                fiedValue.setVT((byte) 1);
                fiedValue.setValue(lineStatus);
                arrayList.add(fiedValue);
            }
            respFriendAddRole.setList(arrayList);
            MessagePusher.pushMessage(toRole, respFriendAddRole);

        }

        {
            RespFriendUpdatePartial updatePartial = new RespFriendUpdatePartial();
            updatePartial.setName(friend.getFriendName());
            updatePartial.setUpdate_type((short) 2);
            updatePartial.setType(group);
            ArrayList<FiedValue> arrayList = new ArrayList<>();
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 301);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 304);
                fiedValue.setVT((byte) 4);
                fiedValue.setValue("");
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 302);
                fiedValue.setVT((byte) 1);
                fiedValue.setValue((byte) 0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 334);
                fiedValue.setVT((byte) 1);
                fiedValue.setValue((byte) 0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 292);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(roleView.getRoleIcon());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType(FieldValuePosConst.LEVEL);
                fiedValue.setVT((byte) 2);
                fiedValue.setValue(roleView.getLevel());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 3012);//线路名字
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(lineName);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 40);
                fiedValue.setVT((byte) 7);
                fiedValue.setValue(roleView.getRoleIcon());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 290);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 33);//帮派名
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(roleView.getPartyName());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 880);
                fiedValue.setVT((byte) 1);
                fiedValue.setValue((byte) 0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 90);
                fiedValue.setVT((byte) 4);
                fiedValue.setValue("");
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 81);//门派名
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(roleService.getFamilyName(roleView.getPolar()));
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 36);//称号
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(roleView.getCurrTitle());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 291);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 305);//面板ID
                fiedValue.setVT((byte) 4);
                fiedValue.setValue(friend.getGid());
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 27);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(0);
                arrayList.add(fiedValue);
            }
            {
                FiedValue fiedValue = new FiedValue();
                fiedValue.setType((short) 194);//在线状态
                fiedValue.setVT((byte) 1);
                fiedValue.setValue(lineStatus);
                arrayList.add(fiedValue);
            }
            updatePartial.setList(arrayList);
            MessagePusher.pushMessage(toRole, updatePartial);
        }
    }


    /**
     * 修改分组名
     *
     * @param session
     * @param reqEditFriendGroupName
     */
    public void editFriendGroupName(IoSession session, ReqEditFriendGroupName reqEditFriendGroupName) {
        Role role = SessionUtils.getRoleBySession(session);
        if (role == null) return;
        List<FriendGroup> list = role.getFriendBox().getFriendGroup();
        for (FriendGroup friendGroup : list) {
            if (friendGroup.getNumber().equals(reqEditFriendGroupName.getFriendGroup().getNumber())) {
                for (FriendGroup oldFriendGroup : list) {
                    if (oldFriendGroup.getGroupName().equals(reqEditFriendGroupName.getFriendGroup().getGroupName())) {
                        MessagePusher.pushMessage(session, new RespMsg("分组名已存在。"));
                        return;
                    }
                }
                friendGroup.setGroupName(reqEditFriendGroupName.getFriendGroup().getGroupName());
                MessagePusher.pushMessage(session, new RespMsg("修改名称成功。"));

                role.getFriendBox().setFriendGroup(list);
                role.save();
                RespFriendRefreshGroup respFriendRefreshGroup = new RespFriendRefreshGroup();
                respFriendRefreshGroup.setFriendGroup(reqEditFriendGroupName.getFriendGroup());
                MessagePusher.pushMessage(session, respFriendRefreshGroup);
                return;
            }
        }
    }

    /**
     * 移动好友分组
     *
     * @param session
     * @param reqMoveFriendGroup
     */
    public void moveFriendGroup(IoSession session, ReqMoveFriendGroup reqMoveFriendGroup) {
        Role role = SessionUtils.getRoleBySession(session);
        if (role == null) return;
        String[] moveList = reqMoveFriendGroup.getName().split(";");
        String[] moveGidList = reqMoveFriendGroup.getMianbanId().split(";");
        int index = 0;
        for (String string : moveList) {
            if (Strings.isEmpty(string)) {
                continue;
            }
            String friendGid = moveGidList[index];
            String oldFriendGroupNumber = reqMoveFriendGroup.getOldGroupNumber();
            String newFriendGroupNumber = reqMoveFriendGroup.getNewGroupNumber();
            List<FriendGroup> list = role.getFriendBox().getFriendGroup();
            String newGroupName = "";
            for (FriendGroup friendGroup : list) {
                if (friendGroup.getNumber().equals(newFriendGroupNumber)) {
                    newGroupName = friendGroup.getGroupName();
                    break;
                }
            }
            index++;
            /**
             * 修改数据库和内存好友信息
             */
            Friend friend = role.getFriendBox().getFriendByName(string);
            if (friend == null) {
                return;
            }
            friend.setGroupNumber(newFriendGroupNumber);
            role.save();
            RespMoveFriendGroup respMoveFriendGroup = new RespMoveFriendGroup();
            ArrayList<String> gids = new ArrayList<>();
            gids.add(friendGid);
            respMoveFriendGroup.setGids(gids);
            respMoveFriendGroup.setToId(newFriendGroupNumber);
            respMoveFriendGroup.setFromId(oldFriendGroupNumber);
            MessagePusher.pushMessage(session, respMoveFriendGroup);

            MessagePusher.pushMessage(session, new RespNotifyMisc("已将#Y" + string + "#n移入#R" + newGroupName + "#n分组中。"));
        }
        MessagePusher.pushMessage(session, new RespMsg("好友移动分组成功。"));
    }


    /**
     * 删除好友分组
     *
     * @param session
     * @param reqRemoveFriendGroup
     */
    public void removeFriendGroup(IoSession session, ReqRemoveFriendGroup reqRemoveFriendGroup) {
        String removeNumber = reqRemoveFriendGroup.getGroupNumber();
        if (removeNumber.equals("1")) {
            MessagePusher.pushMessage(session, new RespMsg("默认分组无法删除。"));
            return;
        }
        Role role = SessionUtils.getRoleBySession(session);
        List<FriendGroup> list = role.getFriendBox().getFriendGroup();
        for (FriendGroup friendGroup : list) {
            if (removeNumber.equals(friendGroup.getNumber())) {
                list.remove(friendGroup);
                break;
            }
        }
        for (Friend friend : role.getFriendBox().getFriends()) {
            if (friend.getGroupNumber().equals(removeNumber)) {
                friend.setGroupNumber("1");
                RespMoveFriendGroup respMoveFriendGroup = new RespMoveFriendGroup();
                ArrayList<String> gids = new ArrayList<>();
                gids.add(friend.getGid());
                respMoveFriendGroup.setGids(gids);
                respMoveFriendGroup.setToId("1");
                respMoveFriendGroup.setFromId(removeNumber);
                MessagePusher.pushMessage(session, respMoveFriendGroup);
            }
        }
        role.save();
        MessagePusher.pushMessage(session, new RespRemoveFriendGroup(removeNumber));
        MessagePusher.pushMessage(session, new RespMsg("分组删除成功。"));
    }

    /**
     * 上下线通知 加了自己好友的角色
     */
    private void sendOnlineStatus(Role role, boolean isOnline) {
//        List<Long> list = DataCache.BE_ADD_FRIENDS.get(role.getUid());
//        if (list != null && list.size() > 0) {
            Server server = serverService.getServer();
            RespNotifyMisc respNotifyMisc = null;
            RespFriendNotification respFriendNotification = new RespFriendNotification();
            respFriendNotification.setRoleName(role.getName());
            respFriendNotification.setServerSonName(server.getSonName());
            if (isOnline) {
                respFriendNotification.setStatus((short) 1);//上线
                respNotifyMisc = new RespNotifyMisc(I18nIdDataPool.getI18nContent(I18nId.PMT_1314, role.getName()));
            } else {
                respFriendNotification.setStatus((short) 2);//下线
                respNotifyMisc = new RespNotifyMisc(I18nIdDataPool.getI18nContent(I18nId.PMT_1315, role.getName()));
            }
            for (Friend friend : role.getFriendBox().getFriends()) {
                Role friendRole = SpringUtils.getRoleService().getOnlinePlayer(Long.parseLong(friend.getGid()));
                if (friendRole == null) {continue;}

                MessagePusher.pushMessage(friendRole, respFriendNotification);
                MessagePusher.pushMessage(friendRole, respNotifyMisc);

            }
//            for (long uid : list) {
//                Role friendRole = SpringUtils.getRoleService().getOnlinePlayer(uid);
//                if (friendRole == null) {continue;}
//
//                MessagePusher.pushMessage(friendRole, respFriendNotification);
//                MessagePusher.pushMessage(friendRole, respNotifyMisc);
//            }
//        }
    }




    /**
     * 修改好友备注
     *
     * @param session
     * @param reqFriendMark
     */
    public void friendMark(IoSession session, ReqFriendMark reqFriendMark) {
        Role role = SessionUtils.getRoleBySession(session);
        if (role == null) return;
        Friend friend = role.getFriendBox().getFriendByGid(reqFriendMark.getGid());
        if (friend == null) {
            return;
        }
        friend.setMark(reqFriendMark.getMemo());
        sendFriendMemo(session, reqFriendMark.getGid(), reqFriendMark.getMemo());
        role.save();
        MessagePusher.pushMessage(session, new RespMsg("设置成功。"));
    }

    /**
     * 发送好友备注
     *
     * @param session
     * @param gid
     * @param memo
     */
    private void sendFriendMemo(IoSession session, String gid, String memo) {
        RespFriendMemo respFriendMemo = new RespFriendMemo();
        ArrayList<FriendMemo> friendMemos = new ArrayList<>();
        FriendMemo friendMemo = new FriendMemo();
        friendMemo.setGid(gid);
        friendMemo.setMemo(memo);
        friendMemos.add(friendMemo);
        respFriendMemo.setFriendMemos(friendMemos);
        MessagePusher.pushMessage(session, respFriendMemo);
    }

    /**
     * 发送好友消息
     *
     * @param role
     * @param reqSendFriendMsg
     */
    public void sendFriendMsg(Role role, ReqSendFriendMsg reqSendFriendMsg) {
        long now = System.currentTimeMillis();
        if (role.getWordTime() > now) {
            return;
        }
//        if (true){
//            return;
//        }
//        if (role.getTotalCharge() <20){
//            MessagePusher.pushMessage(role, new RespNotifyMiscEx("没有充值不能聊天！"));
//            return;
//        }
//        if (SpringUtils.getBean(ServerService.class).getNeice() == 100){
//            MessagePusher.pushMessage(role, new RespNotifyMiscEx("内测中，不能私聊！"));
//            return;
//        }
        String recvName = reqSendFriendMsg.getFriendName();
        long recvUid = SpringUtils.getPlayerService().getUidBy(recvName);
        Role friendRole = SpringUtils.getRoleService().getPlayerBy(recvUid);
        Short strangerLevel = getStrangerLevel(recvUid);
        if (strangerLevel != null && role.getLevel() < strangerLevel) {
            MessagePusher.notify2Player(role, I18nId.PMT_1317);
            return;
        }

        int sendTime = (int) (now / TimeUtil.ONE_SECOND);
        List<FiedValue> list = FieldUtils.getFriendChatList(role);
        list.add(new FiedValue(814, String.valueOf(recvUid)));//面板ID
        RespChat respChat = getRespChat(role.getRoleId(), role.getName(), list, sendTime, reqSendFriendMsg.getMsg(), reqSendFriendMsg.getToken(), reqSendFriendMsg.getVoiceTime());
        logger.error("私聊内容=={}", Json.toJson(respChat, JsonFormat.compact()));
        SpringUtils.getChatService().privateChat(role,friendRole,respChat.getMsg());
        MessagePusher.pushMessage(role, respChat);

        if (isStrange(role, recvName)) {
            /**连续与陌生人私聊次数*/
            if (role.getFriendBox().getChatCount(recvUid) >= 10) {
                MessagePusher.notify2Player(role, I18nId.PMT_1316);
                return ;
            }
            return;
        } else if (isFriend(role, recvName)) {
            /**连续与好友私聊次数*/
            if (role.getFriendBox().getChatCount(recvUid) >= 100) {
                MessagePusher.notify2Player(role, I18nId.PMT_1318);
                return ;
            }
        }

        /**记录与对方的私聊次数*/
        role.getFriendBox().addChatCount(recvUid);

//        Role friendRole = SpringUtils.getRoleService().getOnlinePlayer(recvUid);
        if (friendRole != null) {
            /**在对方黑名单时，对方收不到消息*/
            if (isBlack(friendRole, role.getName())) {
                return ;
            }

            /**不是对方好友且等级小于80同时不是会员时，不能私聊*/
            if (role.getLevel() < 80 && !role.isVip() && !isFriend(friendRole, role.getName())) {
                MessagePusher.pushMessage(role, new RespMsg("购买会员方可私聊。"));
                return ;
            }

            /**清空对方发的私聊的数量*/
            ThreadLocalUtil.addLocalTask(friendRole, () -> friendRole.getFriendBox().removeChatCount(role.getUid()));
            MessagePusher.pushMessage(friendRole, respChat);

            /**自动回复*/
            boolean isAutoReply = (friendRole.getExtendBox().getSetMap().getOrDefault("auto_reply_msg", 0) == 1 ? true : false);
            if (isAutoReply && StringUtils.isNotEmpty(friendRole.getFriendBox().getAutoReplyMsg())) {
                list = FieldUtils.getFriendChatList(friendRole);
                list.add(new FiedValue(814, String.valueOf(role.getUid())));//面板ID
                respChat = getRespChat(friendRole.getRoleId(), friendRole.getName(), list, sendTime, friendRole.getFriendBox().getAutoReplyMsg(), null, 0);
                MessagePusher.pushMessage(role, respChat);
                MessagePusher.pushMessage(friendRole, respChat);
            }
        } else {
            /**离线时，加到离线消息缓存中，对方上线时发给对方*/
            addOfflineMessage(role, recvUid, reqSendFriendMsg.getMsg(), reqSendFriendMsg.getToken(), reqSendFriendMsg.getVoiceTime(), sendTime);
        }
    }

    private short getStrangerLevel(long uid) {
        Role role = roleService.getOnlinePlayer(uid);
        if (role != null) {
            if (roleService.isOpenSet(role,"refuse_stranger_msg")) {return role.getFriendBox().getStrangerLevel();}
        } else {
            PlayerProfile playerProfile = SpringUtils.getPlayerService().queryPlayerProfile(uid);
            if (playerProfile != null) {return playerProfile.getStrangerLevel();}
        }

        return 0;
    }

    private RespChat getRespChat(int sendRoleId, String sendName, List<FiedValue> sendFields, int sendTime, String msg, String token, int voiceTime) {
        
    	NutMap propsStatus = SpringUtils.getRoleService().getPlayerBy(sendRoleId).getPropsStatus();
        sendFields.add(new FiedValue(3024, propsStatus == null?"":propsStatus.getString("liaotiandikuang","")));//聊天框
        sendFields.add(new FiedValue(3023, propsStatus == null ?"":propsStatus.getString("touxiangkuang",""))); // 头像框
        
    	RespChat respChat = new RespChat();
        if (!Strings.isEmpty(token)) {
            respChat.setToken(token);
            respChat.setMsgType((short) 1);
            respChat.setVoiceTime(voiceTime);
            respChat.setCheckSum(968048343);
        }
        respChat.setMsg(msg);
        respChat.setType(ChatConst.FRIEND);
        respChat.setList(sendFields);
        respChat.setRoleName(sendName);
        Server server = serverService.getServer();
        respChat.setLineName(server.getSonName());
        respChat.setRoleId(sendRoleId);
        respChat.setTime(sendTime);
        return respChat;
    }

    /***
     * 添加离线消息
     */
    private void addOfflineMessage(Role role, long recvUid, String msg, String token, int voiceTime, int sendTime) {
        RoleOfflineMessage roleOfflineMessage = DataCache.OFFLINE_MESSAGES.computeIfAbsent(recvUid, k -> new RoleOfflineMessage());
        long sendUid = role.getUid();
        roleOfflineMessage.add(sendUid, sendTime, msg, token, voiceTime);
    }

    /**
     * 发送这个玩家收到的离线消息(一般在登录时候发送)
     */
    public void sendOfflineMessageLogin(Role role) {
        if (role == null) {return ;}
        RoleOfflineMessage roleOfflineMessage = DataCache.OFFLINE_MESSAGES.remove(role.getUid());
        /**没有离线消息时返回*/
        if (roleOfflineMessage == null) {return ;}

        sendOfflineMessage(role, roleOfflineMessage);
    }

    private void sendOfflineMessage(Role role, RoleOfflineMessage roleOfflineMessage) {
        if (role == null || roleOfflineMessage == null) {return ;}

        if (roleOfflineMessage.getMessageMap() == null) {return ;}

        Set<Long> sendUids = roleOfflineMessage.getMessageMap().keySet();
        for (long uid : sendUids) {
            List<OfflineMessage> messages = roleOfflineMessage.getMessageMap().remove(uid);
            PlayerProfile playerProfile = SpringUtils.getPlayerService().queryPlayerProfile(uid);

            /**在黑名单时，收不到消息*/
            if (isBlack(role, playerProfile.getName())) {
                continue;
            }

            List<FiedValue> list = FieldUtils.getFriendChatList(String.valueOf(playerProfile.getGid()), playerProfile.getLevel(), playerProfile.getRoleIcon());
            list.add(new FiedValue(814, role.getGid()));//面板ID

            RespChat respChat = null;
            for (OfflineMessage message : messages) {
                respChat = getRespChat(playerProfile.getRoleId(), playerProfile.getName(), list, message.getTime(), message.getMsg(), message.getToken(), message.getVoiceTime());
                MessagePusher.pushMessage(role, respChat);
            }
        }
    }

    public void searchFriend(IoSession session, ReqSearchFriend reqSearchFriend) {
        Role friendRole = SpringUtils.getRoleService().getOnlinePlayer(reqSearchFriend.getName());
        if (friendRole == null) {
            MessagePusher.pushMessage(session, new RespMsg("搜索玩家不在线或不存在。"));
        } else {
            RespSearchFriend respSearchFriend = new RespSearchFriend();
            ArrayList<SearchFriend> arrayList = new ArrayList<>();
            SearchFriend searchFriend = new SearchFriend();
            searchFriend.setList(FieldUtils.searchFriend(friendRole));
            arrayList.add(searchFriend);
            respSearchFriend.setList(arrayList);
            MessagePusher.pushMessage(session, respSearchFriend);
        }

    }

    /**
     * 设置拒绝陌生人等级
     *
     * @param session
     * @param reqStrangerLevel
     */
    public void setStrangerLevel(IoSession session, ReqStrangerLevel reqStrangerLevel) {
        Role role = SessionUtils.getRoleBySession(session);
        role.getFriendBox().setStrangerLevel(reqStrangerLevel.getLevel());
        role.save();
        refreshFriendSetting(role, (short) 3009, reqStrangerLevel.getLevel());
    }

    /**
     * 设置拒绝添加等级
     *
     * @param session
     * @param reqRefuseLevel
     */
    public void setRefuseLevel(IoSession session, ReqRefuseLevel reqRefuseLevel) {
        Role role = SessionUtils.getRoleBySession(session);
        role.getFriendBox().setRefuseLevel(reqRefuseLevel.getLevel());
        role.save();
        refreshFriendSetting(role, (short) 3011, reqRefuseLevel.getLevel());
    }

    /**
     * 刷新好友设置
     *
     * @param role
     * @param type
     * @param level
     */
    private void refreshFriendSetting(Role role, short type, short level) {
        List<FiedValue> list = new ArrayList<>();
        list.add(new FiedValue(type,level));
        RespUpdate respUpdate = new RespUpdate();
        respUpdate.setRoleId(role.getRoleId());
        respUpdate.setList(list);
        MessagePusher.pushMessage(role, respUpdate);
    }

    /**
     * 添加黑名单
     */
    public void reqAddBlack(Role role, String name) {
        long uid = SpringUtils.getPlayerService().getUidBy(name);
        /**找不到对应名字的玩家时*/
        if (uid <= 0) {
            return ;
        }

        /**对方离线时也可以加入黑名单*/
        if (isFriend(role, name)) {
            /**弹出二次确认框*/
            role.setConfirm(new AddBlackConfirm(name));

            String content = I18nIdDataPool.getI18nContent(I18nId.PMT_1308, name, name);
            RespConfirm respConfirm = new RespConfirm();
            respConfirm.setTips(content);
            MessagePusher.pushMessage(role, respConfirm);
        } else {
            doAddBlack(role, new RoleView(uid));
        }
    }

    /**
     * 是否role的好友
     */
    public boolean isFriend(Role role, String targetName) {
        Friend friend = role.getFriendBox().getFriendByName(targetName);
        if (friend == null) {
            return false;
        }
        if (friend.getGroupNumber().equals("1")) {
            return true;
        }
        return false;
    }

    /**
     * 是否role的黑名单中
     */
    public boolean isBlack(Role role, String targetName) {
        Friend friend = role.getFriendBox().getFriendByName(targetName);
        if (friend == null) {
            return false;
        }
        if (friend.getGroupNumber().equals("5")) {
            return true;
        }
        return false;
    }


    /**
     * 是否role的陌生人
     */
    public boolean isStrange(Role role, String targetName) {
        return !isFriend(role, targetName) && !isBlack(role, targetName);
    }

    /**
     * 确认加入黑名单
     * 加入对象为好友时才需要二次确认
     */
    public void confirmAddBlack(Role role, String targetName) {
        /**先删除好友*/
        doRemoveFriend(role, targetName);

        /**再加入黑名单*/
        doRemoveBlack(role, targetName);
    }

    /**
     * 删除好友
     */
    private void doRemoveFriend(Role role, String targetName) {
        if (role == null) {
            return;
        }

        Friend friend = role.getFriendBox().getFriendByName(targetName);
//        if (friend == null) {
//            /**不是好友*/
//            return;
//        }

        //删除好友
        role.getFriendBox().removeFriend(friend);
        role.save();

        removeBeFriend(role.getUid(), Long.parseLong(friend.getGid()));

        RespRemoveFriend respRemoveFriend = new RespRemoveFriend();
        respRemoveFriend.setFriendName(targetName);
        respRemoveFriend.setFriendGid(friend.getGid());
        respRemoveFriend.setGroupId("1");
        MessagePusher.pushMessage(role, respRemoveFriend);

//        sendFriendInfo(role, friend, "6");

        MessagePusher.notify2Player(role, I18nId.PMT_1309, targetName, targetName);
    }

    /**
     * 加入黑名单
     */
    private void doAddBlack(Role role, RoleView roleView) {
        Friend friend = newFriend(roleView.getGid(), roleView.getName(), "5");
        addFriend(role, friend);//插入数据库

        sendFriendInfo(role, friend, "5");
        MessagePusher.notify2Player(role, I18nId.PMT_1310, roleView.getName());
    }

    /**
     * 移出黑名单
     */
    private void doRemoveBlack(Role role, String name) {
        if (role == null) {
            return;
        }
        Friend friend = role.getFriendBox().getFriendByName(name);
        if (friend == null) {
            return;
        }
        /**在黑名单*/
        if (!friend.getGroupNumber().equals("5")) {
            return ;
        }

        /**从黑名单删除*/
        role.getFriendBox().removeFriend(friend);
        role.save();

        RespRemoveFriend respRemoveFriend = new RespRemoveFriend();
        respRemoveFriend.setFriendName(name);
        respRemoveFriend.setFriendGid(friend.getGid());
        respRemoveFriend.setGroupId(friend.getGroupNumber());
        MessagePusher.pushMessage(role, respRemoveFriend);

//        sendFriendInfo(role, friend, "6");

        MessagePusher.notify2Player(role, I18nId.PMT_1311, name);
    }

    /**
     * 删除好友
     */
    public void removeFriend(Role role, String friendName) {
        doRemoveFriend(role, friendName);
    }

    /**
     * 移出黑名单
     */
    public void removeBlack(Role role, String friendName) {
        doRemoveBlack(role, friendName);
    }

    private void addBeFriend(long uid, long friendUid) {
        List<Long> list = DataCache.BE_ADD_FRIENDS.computeIfAbsent(friendUid, k -> new CopyOnWriteArrayList<>());
        if (!list.contains(uid)) {
            list.add(uid);
        }
    }

    private void removeBeFriend(long uid, long friendUid) {
        List<Long> list = DataCache.BE_ADD_FRIENDS.get(friendUid);
        if (list != null) {
            list.remove(uid);
        }
    }

    private void addBeFriend(Role role) {
        if (role == null) {return ;}
        if (role.getFriendBox().getFriends() == null) {return ;}

        for (Friend friend : role.getFriendBox().getFriends()) {
            addBeFriend(role.getUid(), Long.parseLong(friend.getGid()));
        }
    }

    private void removeBeFriend(Role role) {
        if (role == null) {return ;}
        if (role.getFriendBox().getFriends() == null) {return ;}

        for (Friend friend : role.getFriendBox().getFriends()) {
            removeBeFriend(role.getUid(), Long.parseLong(friend.getGid()));
        }
    }

    public void loadCommon() {
        Dao dao = SpringUtils.getBean(Dao.class);
        //RoleOfflineData roleOfflineData = dao.fetch(RoleOfflineData.class, "offline_messages");
        CommonFetchedData roleOfflineData = dao.fetch(CommonFetchedData.class, CommonConst.offline_messages);
        if (roleOfflineData != null) {
            Map<Long, RoleOfflineMessage> offlineMessages = JsonUtils.string2Map(roleOfflineData.getData(), Long.class, RoleOfflineMessage.class);
            if (offlineMessages != null) {
                DataCache.OFFLINE_MESSAGES.putAll(offlineMessages);
            }
        }
    }

    @PreDestroy
    private void shutDown() {
        saveCommon();
    }

    private void saveCommon() {
        Dao dao = SpringUtils.getBean(Dao.class);
        String data = JsonUtils.map2String(DataCache.OFFLINE_MESSAGES);
        dao.insertOrUpdate(new CommonFetchedData("offline_messages", data));
    }

    public void reqSetAutoReply(Role role, String content) {
        role.getFriendBox().setAutoReplyMsg(content);
        role.save();

        List<FiedValue> list = new ArrayList<>();
        list.add(new FiedValue(3010,content));
        RespUpdate respUpdate = new RespUpdate();
        respUpdate.setRoleId(role.getRoleId());
        respUpdate.setList(list);
        MessagePusher.pushMessage(role, respUpdate);
    }


    /**
     * 请求联系卖家
     */
    public void contactSeller(Role role, String type, String goodsGid, String para) {
        Goods goods = null;
        if(type.equals("集市")) {
            goods =SpringUtils.getBean(MarketService.class).getGoodsById(Long.parseLong(goodsGid));
        } else if(type.equals("珍宝")) {
            goods =SpringUtils.getBean(ZhenbaoService.class).getZhenbaoById(Long.parseLong(goodsGid));
        }
        if (goods == null) {
            MessagePusher.notify2Player(role, I18nId.PMT_1320);
            return ;
        }

        long sellerUid = goods.getRoleId();
        RespFriendAddRole respFriendAddRole = SpringUtils.getFriendService().getRespFriendAddRole(role, sellerUid);
        MessagePusher.pushMessage(role, respFriendAddRole);

        RespExchangeContactSeller respExchangeContactSeller = getRespExchangeContactSeller(role, sellerUid, type, goodsGid, para, goods);
        MessagePusher.pushMessage(role, respExchangeContactSeller);

        RespFriendUpdatePartial respFriendUpdatePartial = SpringUtils.getFriendService().getRespFriendUpdatePartial(role, sellerUid);
        MessagePusher.pushMessage(role, respFriendUpdatePartial);
    }

    public RespExchangeContactSeller getRespExchangeContactSeller(Role role, long sellerUid, String type, String goodsGid, String para, Goods goods) {
        RoleView roleView = new RoleView(sellerUid);
        RespExchangeContactSeller respExchangeContactSeller = new RespExchangeContactSeller();
        respExchangeContactSeller.setType(type);
        respExchangeContactSeller.setGoodsGid(goodsGid);
        respExchangeContactSeller.setPara(para);
        respExchangeContactSeller.setGid(String.valueOf(sellerUid));
        respExchangeContactSeller.setName(roleView.getName());
        respExchangeContactSeller.setLevel(roleView.getLevel());
        respExchangeContactSeller.setIcon(roleView.getRoleIcon());
        boolean isFriend = SpringUtils.getFriendService().isFriend(role, roleView.getName());
        respExchangeContactSeller.setFriend(isFriend);
        respExchangeContactSeller.setOnline(roleView.isOnline());
        respExchangeContactSeller.setGoodsName(goods.getName());
        return respExchangeContactSeller;
    }

    public RespFriendAddRole getRespFriendAddRole(Role role, long uid) {
        RoleView roleView = new RoleView(uid);
        boolean isOnline = roleView.isOnline();
        boolean isFriend = isFriend(role, roleView.getName());

        RespFriendAddRole respFriendAddRole = new RespFriendAddRole();
        respFriendAddRole.setName(roleView.getName());
        respFriendAddRole.setType1((short) 1);
        respFriendAddRole.setType(isFriend ? "1" : "6"); //1好友列表 6应该是陌生人
        String lineName = isOnline ? serverService.getServer().getSonName() : "不在线";
        respFriendAddRole.setLineName(lineName);
        ArrayList<FiedValue> arrayList = new ArrayList<>();
        arrayList.add(new FiedValue(301, 0));
        arrayList.add(new FiedValue(304, ""));
        arrayList.add(new FiedValue(302, 0));
        arrayList.add(new FiedValue(334, 0));
        arrayList.add(new FiedValue(292, roleView.getRoleIcon()));
        arrayList.add(new FiedValue(31, roleView.getLevel()));
        arrayList.add(new FiedValue(3012, lineName));
        arrayList.add(new FiedValue(40, roleView.getRoleIcon()));
        arrayList.add(new FiedValue(290, roleView.getWeaponIcon()));//weapon_icon
        arrayList.add(new FiedValue(33, roleView.getPartyName()));//帮派名
        arrayList.add(new FiedValue(880, (byte) 0));
        arrayList.add(new FiedValue(90, ""));
        arrayList.add(new FiedValue(81, roleService.getFamilyName(roleView.getPolar())));//门派名
        arrayList.add(new FiedValue(36, roleView.getCurrTitle()));//称号
        arrayList.add(new FiedValue(291, 0));
        arrayList.add(new FiedValue(305, String.valueOf(uid)));//面板ID
        arrayList.add(new FiedValue(27, 0));
        arrayList.add(new FiedValue(21, 0));
        arrayList.add(new FiedValue(194, (byte) (isOnline ? 1 : 2)));//在线状态
        respFriendAddRole.setList(arrayList);

        return respFriendAddRole;
    }

    public RespFriendUpdatePartial getRespFriendUpdatePartial(Role role, long uid) {
        RoleView roleView = new RoleView(uid);
        boolean isOnline = roleView.isOnline();
        boolean isFriend = isFriend(role, roleView.getName());

        RespFriendUpdatePartial updatePartial = new RespFriendUpdatePartial();
        updatePartial.setName(roleView.getName());
        updatePartial.setUpdate_type((short) 2);
        updatePartial.setType(isFriend ? "1" : "6");
        ArrayList<FiedValue> arrayList = new ArrayList<>();
        arrayList.add(new FiedValue(301, 0));
        arrayList.add(new FiedValue(304, ""));
        arrayList.add(new FiedValue(302, 0));
        arrayList.add(new FiedValue(334, (byte) 0));
        arrayList.add(new FiedValue(292, roleView.getRoleIcon()));
        arrayList.add(new FiedValue(FieldValuePosConst.LEVEL, roleView.getLevel()));
        arrayList.add(new FiedValue(3012, isOnline ? serverService.getServer().getSonName() : "不在线"));//线路名字
        arrayList.add(new FiedValue(40, roleView.getRoleIcon()));
        arrayList.add(new FiedValue(290, 0));
        arrayList.add(new FiedValue(33, roleView.getPartyName()));//帮派名
        arrayList.add(new FiedValue(880, (byte) 0));
        arrayList.add(new FiedValue(90, ""));
        arrayList.add(new FiedValue((short) 81, roleService.getFamilyName(roleView.getPolar())));//门派名
        arrayList.add(new FiedValue((short) 36, roleView.getCurrTitle()));//称号
        arrayList.add(new FiedValue((short) 291, 0));
        arrayList.add(new FiedValue((short) 305, String.valueOf(uid)));//面板ID
        arrayList.add(new FiedValue((short) 27, 0));
        arrayList.add(new FiedValue((short) 194, (byte) (isOnline ? 1 : 2)));//在线状态
        updatePartial.setList(arrayList);

        return updatePartial;
    }
    public void applyFriendItem(Role role, ReqApplyFriendItem reqApplyFriendItem) {
        IoSession session = SessionUtils.getSessionBy(role.getUid().longValue());
        String items = reqApplyFriendItem.getItems();
        String gid = reqApplyFriendItem.getGid();
        String name = reqApplyFriendItem.getName();
        long friendUid = this.playerService.getUidBy(name);
        IoSession friendSession = SessionUtils.getSessionBy(friendUid);
        Role friendRole = SessionUtils.getRoleBySession(friendSession);
        String[] itemStrs = items.substring(1).split("\\|");
        int[] allPos = new int[itemStrs.length];
        int i;
        for (i = 0; i < itemStrs.length; i++) {
            allPos[i] = Integer.parseInt(itemStrs[i]);
        }
        for (i = 0; i < allPos.length; i++) {
            this.equipService.useItem((byte) allPos[i], (short) 1, session);
        }
        int curFriend = role.getFriendBox().getFriendByGid(gid).getFriendliness();
        this.logger.error("before送礼物, 友好度=" + curFriend);
        int addFriend = allPos.length * 88;
        int finalFriend = curFriend + addFriend;
        role.getFriendBox().getFriendByGid(gid).setFriendliness(finalFriend);
        friendRole.getFriendBox().getFriendByGid(role.getGid()).setFriendliness(finalFriend);
        this.logger.error("after送礼物, 友好度=" + finalFriend);
        role.save();
        friendRole.save();
        RespFriendUpdatePartial respFriendUpdatePartial = new RespFriendUpdatePartial();
        respFriendUpdatePartial.setUpdate_type((short) 1);
        respFriendUpdatePartial.setType("1");
        respFriendUpdatePartial.setName(name);
        List<FiedValue> fields = new ArrayList<>();
        fields.add(new FiedValue(305, gid));
        fields.add(new FiedValue(21, Integer.valueOf(finalFriend)));
        respFriendUpdatePartial.setList(fields);
        MessagePusher.pushMessage(role, (Message) respFriendUpdatePartial);
        RespFriendUpdatePartial respFriendUpdatePartial2 = new RespFriendUpdatePartial();
        respFriendUpdatePartial2.setUpdate_type((short) 1);
        respFriendUpdatePartial2.setType("1");
        respFriendUpdatePartial2.setName(role.getName());
        List<FiedValue> fields2 = new ArrayList<>();
        fields2.add(new FiedValue(305, role.getGid()));
        fields2.add(new FiedValue(21, Integer.valueOf(finalFriend)));
        respFriendUpdatePartial2.setList(fields2);
        MessagePusher.pushMessage(friendRole, (Message) respFriendUpdatePartial2);
        RespApplyFriendItemResult respApplyFriendItemResult = new RespApplyFriendItemResult();
        respApplyFriendItemResult.setResult((byte) 1);
        respApplyFriendItemResult.setGid(gid);
        MessagePusher.pushMessage(role, (Message) respApplyFriendItemResult);

    }
}
